﻿Imports System.IO
Imports System.Reflection
Imports System.Text

Public Class ucFiles
    Dim mAppFileitem As AppFileItem
    Private Sub ucFiles_Load(sender As Object, e As EventArgs) Handles Me.Load
        lblAppFileHeader.Text = "Application Files: " & gUDApp.SelectedApp.ApplicationTitle

        lvwAppFiles.Columns(0).AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent)
        lvwAppFiles.Columns(1).AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent)
        lvwAppFiles.Columns(2).AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent)
        lvwAppFiles.Columns(3).AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent)
        lvwAppFiles.Columns(4).AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent)
        lvwAppFiles.Columns(5).AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent)

        Extensions = New Dictionary(Of [String], [String])()
        Extensions.Add("exe", "Executable(s)")
        Extensions.Add("dll", "Assemblies or dll(s)")
        Extensions.Add("oth", "Other Included Files(s)")
        Extensions.Add("ref", "Reference Files(s)")

        For Each kvp As KeyValuePair(Of [String], [String]) In Extensions
            lvwAppFiles.Groups.Add(kvp.Key, kvp.Value)
        Next

        LoadAppDirectories()

        LoadAppFiles(chkInclude.Checked)
    End Sub

#Region "General Loading"
    Sub LoadAppDirectories()
        cmbDirectories.DataSource = gUDApp.SelectedApp.DirectoryList
        cmbDirectories.SelectedIndex = 0
    End Sub
#End Region
#Region "Process ListviewBox"
    Private Sub ListAssembly_DragDrop(sender As Object, e As DragEventArgs) Handles lvwAppFiles.DragDrop
        ProcessFiles(DirectCast(e.Data.GetData(DataFormats.FileDrop), [String]()))
    End Sub
    Private Sub ListAssembly_DragEnter(sender As Object, e As DragEventArgs) Handles lvwAppFiles.DragEnter
        ' make sure they're actually dropping files (not text or anything else)
        If e.Data.GetDataPresent(DataFormats.FileDrop, False) = True Then
            ' allow them to continue
            ' (without this, the cursor stays a "NO" symbol
            e.Effect = DragDropEffects.All
        End If
    End Sub
    Private Sub btnAddFiles_Click(sender As Object, e As EventArgs) Handles btnAddFiles.Click
        openFile1.CheckFileExists = True
        openFile1.Multiselect = True
        openFile1.FileName = [String].Empty
        openFile1.Filter = ".All Files|*.*"

        If openFile1.ShowDialog() = DialogResult.OK Then
            ProcessFiles(openFile1.FileNames)
        End If
    End Sub
#End Region
#Region "Properties"
    Public Property Extensions() As Dictionary(Of [String], [String])
        Get
            Return m_Extensions
        End Get
        Private Set(value As Dictionary(Of [String], [String]))
            m_Extensions = value
        End Set
    End Property
    Private m_Extensions As Dictionary(Of [String], [String])
#End Region
#Region "Process UI"
    Private Sub btnDelFiles_Click(sender As Object, e As EventArgs) Handles btnDelFiles.Click
        For z As Int32 = 0 To lvwAppFiles.Items.Count - 1
            If lvwAppFiles.Items(z).Checked = True Then gAppFile.RemoveFile(CInt(lvwAppFiles.Items(z).Tag))
        Next
        LoadAppFiles(chkInclude.Checked)
    End Sub
    Private Sub btnDelAllFiles_Click(sender As Object, e As EventArgs) Handles btnDelAllFiles.Click
        For z As Int32 = 0 To lvwAppFiles.Items.Count - 1
            gAppFile.RemoveFile(CInt(lvwAppFiles.Items(z).Tag))
        Next
        LoadAppFiles(chkInclude.Checked)
    End Sub
    Private Sub btnDirUpdate_Click(sender As Object, e As EventArgs) Handles btnDirUpdate.Click
        For z As Int32 = 0 To lvwAppFiles.Items.Count - 1
            If lvwAppFiles.Items(z).Checked = True Then
                mAppFileitem = gAppFile.GetAppFile(CInt(lvwAppFiles.Items(z).Tag))
                mAppFileitem.DirectoryID = CInt(cmbDirectories.SelectedValue)
                gAppFile.Save(mAppFileitem)
                lvwAppFiles.Items(z).Checked = False
            End If
        Next
        LoadAppFiles(chkInclude.Checked)
    End Sub
    Private Sub btnExcludeFiles_Click(sender As Object, e As EventArgs) Handles btnExcludeFiles.Click
        For z As Int32 = 0 To lvwAppFiles.Items.Count - 1
            If lvwAppFiles.Items(z).Checked = True Then
                mAppFileitem = gAppFile.GetAppFile(CInt(lvwAppFiles.Items(z).Tag))
                mAppFileitem.IncludeStatus = False
                gAppFile.Save(mAppFileitem)
                lvwAppFiles.Items(z).Checked = False
            End If
        Next
        LoadAppFiles(chkInclude.Checked)
    End Sub
    Private Sub btnIncludeFiles_Click(sender As Object, e As EventArgs) Handles btnIncludeFiles.Click
        For z As Int32 = 0 To lvwAppFiles.Items.Count - 1
            If lvwAppFiles.Items(z).Checked = True Then
                mAppFileitem = gAppFile.GetAppFile(CInt(lvwAppFiles.Items(z).Tag))
                mAppFileitem.IncludeStatus = True
                gAppFile.Save(mAppFileitem)
                lvwAppFiles.Items(z).Checked = False
            End If
        Next
        LoadAppFiles(chkInclude.Checked)
    End Sub
    Private Sub chkInclude_CheckedChanged(sender As Object, e As EventArgs) Handles chkInclude.CheckedChanged
        LoadAppFiles(chkInclude.Checked)
    End Sub
    Private Sub btnSetShortcut_Click(sender As Object, e As EventArgs) Handles btnSetShortcut.Click
        For z As Int32 = 0 To lvwAppFiles.Items.Count - 1
            If lvwAppFiles.Items(z).Checked = True Then
                mAppFileitem = gAppFile.GetAppFile(CInt(lvwAppFiles.Items(z).Tag))
                mAppFileitem.CreateShortCut = True
                gAppFile.Save(mAppFileitem)
                lvwAppFiles.Items(z).Checked = False
            End If
        Next
        LoadAppFiles(chkInclude.Checked)
    End Sub
    Private Sub btnUnsetShortcut_Click(sender As Object, e As EventArgs) Handles btnUnsetShortcut.Click
        For z As Int32 = 0 To lvwAppFiles.Items.Count - 1
            If lvwAppFiles.Items(z).Checked = True Then
                mAppFileitem = gAppFile.GetAppFile(CInt(lvwAppFiles.Items(z).Tag))
                mAppFileitem.CreateShortCut = False
                gAppFile.Save(mAppFileitem)
                lvwAppFiles.Items(z).Checked = False
            End If
        Next
        LoadAppFiles(chkInclude.Checked)
    End Sub
#End Region
#Region "General Functions"
    Private Sub ProcessFiles(filenames As [String]())
        Dim tFileID As Integer
        Dim tUniqueFilename As String
        Dim tListFile As String
        Dim tNewFile As String
        Dim tShortCut As Boolean
        Dim fi As FileInfo

        Dim tFiles As New List(Of AddFiles)

        For i As Int32 = 0 To filenames.Length - 1
            If File.Exists(filenames(i)) = True Then
                tFileID = 0
                tUniqueFilename = ""
                tShortCut = False

                fi = New FileInfo(filenames(i))
                tNewFile = fi.Name.ToUpper.Trim

                If fi.Extension.ToUpper.Trim = ".EXE" Then tShortCut = True

                For Each item In tFiles
                    tListFile = New FileInfo(item.Filename).Name.ToUpper.Trim
                    If tNewFile = tListFile Then
                        tFileID = item.FileID
                        tUniqueFilename = item.UniqueName
                        Exit For
                    End If
                Next

                If tFileID = 0 Then tUniqueFilename = GetUniqueFileName(8, tFiles)
                'UpdateAppFile(filenames(i), 1, tFileID, False, tUniqueFilename, tShortCut)
                tFiles.Add(New AddFiles With {.FileID = tFileID, .Filename = filenames(i), .ShortCut = tShortCut, .UniqueName = tUniqueFilename})

            ElseIf Directory.Exists(filenames(i)) Then
                Dim files As [String]() = Directory.GetFiles(filenames(i))
                ProcessFiles(files)

                Dim directories As [String]() = Directory.GetDirectories(filenames(i))
                ProcessFiles(directories)
            End If
        Next

        For Each item In tFiles
            UpdateAppFile(item.Filename, 1, item.FileID, False, item.UniqueName, item.ShortCut)
        Next

        LoadAppFiles(chkInclude.Checked)
    End Sub
    Sub UpdateAppFile(Filename As String, AppDirectoryID As Integer, AppFileID As Integer, IsReferenceFile As Boolean, UniqueFilename As String, CreateShortCut As Boolean)
        Dim p As New FileInfo(Filename)
        mAppFileitem = New AppFileItem() With {.Fullname = Filename,
                                               .Filename = p.Name,
                                               .DirectoryID = AppDirectoryID,
                                               .ApplicationID = gUDApp.SelectedAppID,
                                               .FileID = AppFileID,
                                               .ReferenceFile = IsReferenceFile,
                                               .UniqueFilename = UniqueFilename,
                                               .CreateShortCut = CreateShortCut}
        gAppFile.Save(mAppFileitem)
    End Sub
    Sub LoadAppFiles(ShowIncludeOnly As Boolean)
        Dim tInclude As Boolean
        UseWaitCursor = True
        lvwAppFiles.Items.Clear()

        lvwAppFiles.BeginUpdate()

        Dim tString As String

        For Each ap In gAppFile.AppFileList
            tInclude = True

            If ShowIncludeOnly = True And ap.IncludeStatus = False Then tInclude = False

            If tInclude = True Then

                If File.Exists(ap.Fullname) = True Then
                    tString = "Available"
                Else
                    tString = "Missing"
                End If

                Dim strExtension As [String] = Path.GetExtension(ap.Fullname).ToLower().TrimStart("."c)
                Dim lvi As ListViewItem = lvwAppFiles.Items.Add(ap.Fullname)

                lvi.SubItems.Add(ReturnDirectoryName(ap.DirectoryID))
                lvi.SubItems.Add(ap.UniqueFilename)
                lvi.SubItems.Add(tString)
                lvi.SubItems.Add(ap.IncludeStatus)

                If ap.CreateShortCut = True Then
                    lvi.SubItems.Add("x")
                Else
                    lvi.SubItems.Add("")
                End If


                lvi.Tag = ap.FileID
                lvi.Group = lvwAppFiles.Groups(ReturnGroupIndicator(ap.ReferenceFile, strExtension))
            End If
        Next

        Dim tFileStatus As SACommon.SAEventArgs.StatusCodes
        If gAppFile.AppFileList.Count > 0 Then
            tFileStatus = SACommon.SAEventArgs.StatusCodes.Defined
        Else
            tFileStatus = SACommon.SAEventArgs.StatusCodes.NewItem
        End If

        gUDApp.NewFileStatus = tFileStatus
        gUDApp.Save(gUDApp.SelectedApp)

        lvwAppFiles.Columns(0).Width = -1
        lvwAppFiles.Columns(1).Width = -1
        lvwAppFiles.Columns(2).Width = -2
        lvwAppFiles.Columns(3).Width = -1
        lvwAppFiles.Columns(4).Width = -2
        lvwAppFiles.Columns(5).Width = -2

        lvwAppFiles.EndUpdate()

        UseWaitCursor = False
    End Sub
    Function ReturnDirectoryName(SelectedDirectoryID As Integer) As String
        Try
            Return (From x In gUDApp.SelectedApp.DirectoryList Where x.DirectoryID = SelectedDirectoryID).First.Directory
        Catch ex As Exception
            Return ""
        End Try
    End Function
    Function ReturnGroupIndicator(ReferenceFile As Boolean, Extension As String) As String
        If ReferenceFile = True Then Return "ref"
        If Extension = "exe" Or Extension = "dll" Then Return Extension
        Return "oth"
    End Function
    Function GetUniqueFileName(Length As Integer, FileList As List(Of AddFiles)) As String
        Dim s As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        Dim r As Random
        Dim sb As StringBuilder
        Dim unique As Boolean
        Dim tName As String

        Do
            sb = New StringBuilder
            r = New Random
            unique = True
            For i As Integer = 1 To Length
                Dim idx As Integer = r.Next(0, 35)
                sb.Append(s.Substring(idx, 1))
            Next
            tName = sb.ToString

            unique = True
            For Each item In FileList
                If item.UniqueName.Trim = tName.Trim Then
                    unique = False
                End If
            Next
        Loop Until unique = True
        Return tName
    End Function
#End Region

    Class AddFiles
        Property Filename As String
        Property FileID As Integer
        Property UniqueName As String
        Property ShortCut As Boolean
    End Class

End Class
